﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Globalization;
using System.Text.RegularExpressions;

namespace Senthil.Mobile.WhereAmI
{
    public static class RouteManager
    {
        static List<Route> routes = new List<Route>();
        public static string appDataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"wami\Routes");
        public static string routeFileExtension = ".txt";

        public static void LoadAllRoutes()
        {
            routes.Clear();

            foreach (string fileName in RouteFiles)
            {
                LoadRoute(fileName);
            }
        }

        public static void Save()
        {
            if (!Directory.Exists(appDataDirectory))
            {
                Directory.CreateDirectory(appDataDirectory);
            }

            foreach (Route route in routes)
            {
                string routeFileName = CreateRouteFileName(route);
                Save(route, routeFileName);
            }
        }

        public static void Save(Route route, string routeFileName)
        {
            using (StreamWriter writer = new StreamWriter(routeFileName))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Route));

                serializer.Serialize(writer, route);
            }
        }

        public static void SaveNew(Route route)
        {
            string routeFileName = CreateRouteFileName(route);

            if (File.Exists(routeFileName))
            {
                string onlyFileName = Path.Combine(Path.GetDirectoryName(routeFileName), Path.GetFileNameWithoutExtension(routeFileName));
                string extension = Path.GetExtension(routeFileName);
                routeFileName = onlyFileName + " " + DateTime.Now.ToString("dd-MM-yy HH-mm-ss") + "." + extension;
            }

            Save(route, routeFileName);
        }

        public static Route LoadRoute(string fileName)
        {
            if (string.IsNullOrEmpty(Path.GetDirectoryName(fileName)))
            {
                fileName = Path.Combine(appDataDirectory, fileName);
            }

            using (StreamReader reader = new StreamReader(fileName))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Route));
                Route route = (Route)serializer.Deserialize(reader);
                route.FixupRoutePoints();
                routes.Add(route);

                return route;
            }
        }

        public static IEnumerable<string> RouteNames
        {
            get
            {
                foreach (string fileName in RouteFiles)
                {
                    yield return Path.GetFileNameWithoutExtension(fileName);
                }
            }
        }

        public static IEnumerable<string> RouteFiles
        {
            get
            {
                if (!Directory.Exists(appDataDirectory))
                {
                    Directory.CreateDirectory(appDataDirectory);
                }

                return Directory.GetFiles(appDataDirectory);
            }
        }

        public static Route LoadRouteByName(string routeName)
        {
            return LoadRoute(Path.ChangeExtension(routeName, routeFileExtension));
        }

        public static IEnumerable<Route> Routes
        {
            get { return routes; }
        }

        public static void AddRoute(Route route)
        {
            routes.Add(route);
        }

        static Regex excludeAlphaNumeralsRegex = new Regex(@"[^\w\d\s]");
        private static string Sanitize(string name)
        {
            return excludeAlphaNumeralsRegex.Replace(name, "");
        }

        private static string CreateRouteFileName(Route route)
        {
            string routeFileName = Path.Combine(appDataDirectory, string.Format(CultureInfo.InvariantCulture, @"Route-{0}.txt", Sanitize(route.Name)));
            return routeFileName;
        }
    }
}
